using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.WebApi.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 场馆会员卡用户领取管理
    /// </summary>
    public class VenueUserCardService : IVenueUserCardService
    {
        private readonly ICurrentInfo _currentInfo;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IVenueUserCardRepository _venueUserCardRepository;
        private readonly IVenueMemberCardRepository _venueMemberCardRepository;
        private readonly IBaseUserRepository _baseUserRepository;
        private readonly IVenueInfoRepository _venueInfoRepository;
        private readonly IBaseUserVenueInfoRelationRepository _venueInfoRelationRepository;
        private readonly IVenueUserCardRecordService _venueUserCardRecordService;

        /// <summary>
        /// ctor
        /// </summary>
        public VenueUserCardService(
            ICurrentInfo currentInfo,
            IUnitOfWorkManager unitOfWorkManager,
            IVenueUserCardRepository venueUserCardRepository,
            IVenueMemberCardRepository venueMemberCardRepository,
            IBaseUserRepository baseUserRepository,
            IBaseUserVenueInfoRelationRepository venueInfoRelationRepository,
            IVenueUserCardRecordService venueUserCardRecordService,
            IVenueInfoRepository venueInfoRepository)
        {
            _currentInfo = currentInfo;
            _unitOfWorkManager = unitOfWorkManager;
            _venueUserCardRepository = venueUserCardRepository;
            _venueMemberCardRepository = venueMemberCardRepository;
            _baseUserRepository = baseUserRepository;
            _venueInfoRelationRepository = venueInfoRelationRepository;
            _venueUserCardRecordService = venueUserCardRecordService;
            _venueInfoRepository = venueInfoRepository;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<VenueUserCardDto> GetAsync(Guid id)
        {
            var queryable = from userCard in _venueUserCardRepository.AsNoTracking()
                            join card in _venueMemberCardRepository.AsNoTracking()
                            on userCard.CardId equals card.ID
                            join user in _baseUserRepository.AsNoTracking()
                            on userCard.UserId equals user.ID
                            join venue in _venueInfoRepository.AsNoTracking()
                            on userCard.VenueId equals venue.ID
                            where userCard.ID == id
                            select new VenueUserCardDto
                            {
                                ID = userCard.ID,
                                UserId = userCard.UserId,
                                CardId = userCard.CardId,
                                CardType = userCard.CardType,
                                RechargeTime = userCard.RechargeTime,
                                ExpireTime = userCard.ExpireTime,
                                Balance = userCard.Balance,
                                TimesCount = userCard.TimesCount,
                                Discount = userCard.Discount,
                                CreateTime = userCard.CreateTime,
                                U_Code = user.U_Code,
                                U_PhoneNum = user.U_PhoneNum,
                                U_Headportrait = user.U_Headportrait,
                                U_NickName = user.U_NickName,
                                VenueId = userCard.VenueId,
                                VenueName = venue.VI_Name,
                                CardName = card.Name,
                                CardRemark = card.Remark,
                            };
            var result = await queryable.FirstOrDefaultAsync();

            return result;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<VenueUserCardDto>> PageListAsync(VenueUserCardPageRequestDto request)
        {
            int.TryParse(request.Key, out var userCode);
            var queryable = from userCard in _venueUserCardRepository.AsNoTracking()
                            join card in _venueMemberCardRepository.AsNoTracking()
                            on userCard.CardId equals card.ID
                            join user in _baseUserRepository.AsNoTracking()
                            on userCard.UserId equals user.ID
                            join venue in _venueInfoRepository.AsNoTracking()
                            on userCard.VenueId equals venue.ID
                            orderby userCard.CreateTime descending
                            select new VenueUserCardDto
                            {
                                ID = userCard.ID,
                                UserId = userCard.UserId,
                                CardId = userCard.CardId,
                                CardType = userCard.CardType,
                                RechargeTime = userCard.RechargeTime,
                                ExpireTime = userCard.ExpireTime,
                                Balance = userCard.Balance,
                                TimesCount = userCard.TimesCount,
                                Discount = userCard.Discount,
                                CreateTime = userCard.CreateTime,
                                U_Code = user.U_Code,
                                U_PhoneNum = user.U_PhoneNum,
                                VenueId = userCard.VenueId,
                                U_Headportrait = user.U_Headportrait,
                                U_NickName = user.U_NickName,
                                VenueName = venue.VI_Name,
                                CardName = card.Name,
                                CardRemark = card.Remark,
                            };
            if (request.UserId != default)
            {
                queryable = queryable.Where(m => m.UserId == request.UserId);
            }

            if (request.CardId != default)
            {
                queryable = queryable.Where(m => m.CardId == request.CardId);
            }

            if (request.UserCardState == UserCardStateEnum.Use)
            {
                queryable = queryable.Where(m => m.ExpireTime >= DateTimeOffset.Now);
            }
            else if (request.UserCardState == UserCardStateEnum.Expired)
            {
                queryable = queryable.Where(m => m.ExpireTime < DateTimeOffset.Now);
            }

            if (!string.IsNullOrWhiteSpace(request.Key))
            {
                queryable = queryable.Where(m => m.U_Code == userCode || m.U_PhoneNum.Contains(request.Key));
            }

            var result = new PageResult<VenueUserCardDto>()
            {
                Total = await queryable.CountAsync(),
                Result = await queryable.Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).ToListAsync(),
            };
            return result;
        }

        /// <summary>
        /// 新增
        /// </summary>
        public async Task<UnaryResult> AddAsync(VenueUserCardAddDto model)
        {
            var venueCard = await _venueMemberCardRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == model.CardId);
            if (venueCard == null)
            {
                return UnaryResult.Faild(10, "场馆会员卡套不存在");
            }

            foreach (var item in model.UserIdList)
            {
                if (await _venueUserCardRepository.AnyAsync(m => m.CardId == model.CardId && m.UserId == item))
                {
                    return UnaryResult.Faild(10, "此用户已办理");
                }
            }

            var entities = new List<VenueUserCard>();
            model.UserIdList.ForEach(userId =>
            {
                var venueUserCard = new VenueUserCard
                {
                    VenueId = venueCard.VenueId,
                    CardId = model.CardId,
                    UserId = userId,
                    CardType = venueCard.CardType,
                    RechargeTime = DateTimeOffset.Now,
                    ExpireTime = DateTimeOffset.Now.AddMonths(venueCard.ValidMonth)
                };
                if (venueCard.CardType == MemberCardTypeEnum.Discount)
                {
                    venueUserCard.Discount = 10;
                }

                entities.Add(venueUserCard);
            });

            await _venueUserCardRepository.BulkAddAsync(entities);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task<UnaryResult> DeleteAsync(Guid id)
        {
            await _venueUserCardRepository.DeleteAsync(p => p.ID == id);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 充值
        /// </summary>
        public async Task<UnaryResult> RechargeAsync(VenueUserCardAmountAddDto model)
        {
            var userCard = await _venueUserCardRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == model.UserCardId);
            if (userCard == null)
            {
                return UnaryResult.Faild(10, "用户会员卡不存在");
            }

            if (userCard.CardType == MemberCardTypeEnum.Discount && (model.Discount <= 0 || model.Discount > 10))
            {
                return UnaryResult.Faild(10, "折扣范围:0.1-10");
            }

            //if (userCard.CardType == MemberCardTypeEnum.Times && model.TimesCount <= 0)
            //{
            //    return UnaryResult.Faild(10, "充值次数<=0");
            //}

            //if (userCard.CardType != MemberCardTypeEnum.Times && model.Amount <= 0)
            //{
            //    return UnaryResult.Faild(10, "充值金额<=0");
            //}

            var user = await _baseUserRepository.AsNoTracking().FirstOrDefaultAsync(m => m.U_OpenId == _currentInfo.MiniProgramOpenId);
            if (user == null)
            {
                return UnaryResult.Faild(10, "未查询到用户信息");
            }

            var venueCard = await _venueMemberCardRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == userCard.CardId);
            if (!await _venueInfoRelationRepository.AsNoTracking().AnyAsync(m => m.BaseUserID == user.ID && m.VenueInfoID == venueCard.VenueId))
            {
                return UnaryResult.Faild(10, "登录用户不是该场馆管理员");
            }

            using (var uow = _unitOfWorkManager.Begin())
            {
                //用户会员卡更新
                userCard = await _venueUserCardRepository.FirstOrDefaultAsync(m => m.ID == model.UserCardId);
                if (userCard.CardType == MemberCardTypeEnum.Times)
                {
                    userCard.TimesCount += model.TimesCount;
                }
                else
                {
                    userCard.Balance += model.Amount;
                }

                if (userCard.CardType == MemberCardTypeEnum.Discount)
                {
                    userCard.Discount = model.Discount;
                }

                userCard.RechargeTime = DateTimeOffset.Now;
                userCard.ExpireTime = DateTimeOffset.Now.AddMonths(venueCard.ValidMonth);
                await _venueUserCardRepository.UpdateAsync(userCard);

                //用户会员卡记录
                var record = new VenueUserCardRecordAddDto
                {
                    VenueId = venueCard.VenueId,
                    UserCardId = userCard.ID,
                    CardType = userCard.CardType,
                    UserId = userCard.UserId,
                    UserCode = user.U_Code,
                    Type = CardRecordTypeEnum.Recharge,
                    Balance = userCard.CardType == MemberCardTypeEnum.Times ? userCard.TimesCount : userCard.Balance,
                    Amount = userCard.CardType == MemberCardTypeEnum.Times ? model.TimesCount : model.Amount,
                    Reamrk = model.TimesCount < 0 || model.Amount < 0 ? "红冲充值" : "用户会员卡充值"
                };

                await _venueUserCardRecordService.AddAsync(record);

                await uow.CompleteAsync();
            }

            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 用户会员卡统计信息
        /// </summary>
        /// <param name="cardId">卡套ID</param>
        public async Task<VenueUserCardStatisticsDto> StatisticsAsync(Guid cardId)
        {
            var total = await _venueUserCardRepository.Where(m => m.CardId == cardId).AsNoTracking().CountAsync();
            var expiredCount = await _venueUserCardRepository.AsNoTracking().Where(m => m.CardId == cardId && m.ExpireTime < DateTimeOffset.Now).CountAsync();
            return new VenueUserCardStatisticsDto
            {
                SaleCount = total,
                ExpiredCount = expiredCount,
                UseCount = total - expiredCount
            };
        }
    }
}
